package socketserver;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.Socket;

import net.ClientCommunicator;
import messages.Message;
import messages.WallMessage;



/**
 * SocketClient
 * 
 * Responsible for managing one client communicating over TCP/IP sockets.
 */
public class SocketClientCommunicator implements ClientCommunicator {
	
	/**
	 * Constructor
	 * 
	 * @param socket The socket that allows communication with the client.
	 */
	public SocketClientCommunicator(Socket socket) throws IOException  {
		this.socket = socket;
		address = socket.getInetAddress();
		
		System.err.println(Thread.currentThread());
		
		this.in  = new ObjectInputStream(socket.getInputStream());
		this.out = new ObjectOutputStream(socket.getOutputStream());			
	}
		
	/**
	 * Reads a message from the socket.
	 * Will block until the message arrives.
	 * @throws ClassNotFoundException 
	 * @throws IOException 
	 */
	public Message receive() {
		try {
			return (Message) this.in.readObject();
		} catch (Exception e) {
			this.close();
			e.printStackTrace();
			// Safely ignore :)
		}
		return null;
	}
	

	/**
	 * Sends a message through the socket.
	 * @throws IOException 
	 */
	public void send(Message message) throws IOException {
		this.out.reset();
		this.out.writeObject(message);
		this.out.flush();
	}
	
	
	/**
	 * Special send method for WallMessages.
	 * 
	 * Why do we need a special method to send these messages? Because we ignore them!
	 * These messages are sent by the SocketServer itself using UDP/multicasting.
	 * So we will ignore them here...
	 */
	public void send(WallMessage message) {	}
	
	
	public void close() {
		return;
		
		/*
		try {
			socket.close();
			in.close();
			out.close();
		} catch (IOException e) {
			e.printStackTrace();
			// Ignore...
		}
		*/
	}
	
	
	public InetAddress getAddress() {
		return this.address;
	}
	
	
	private Socket socket;
	private ObjectInputStream in;
	private ObjectOutputStream out;
	private InetAddress address;
}
